package tech.xs.sys.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import tech.xs.common.framework.domain.annotations.AuthApi;
import tech.xs.common.framework.domain.model.ApiResult;
import tech.xs.common.framework.util.Assert;
import tech.xs.common.sys.domain.constant.PermissionConstant;
import tech.xs.common.util.SyncUtil;
import tech.xs.sys.domain.bo.role.permission.EditRolePermissionBo;
import tech.xs.sys.domain.bo.role.permission.ListAllRolePermissionBo;
import tech.xs.sys.domain.entity.SysPermission;
import tech.xs.sys.domain.entity.SysRole;
import tech.xs.sys.domain.entity.SysRolePermission;
import tech.xs.sys.service.SysPermissionService;
import tech.xs.sys.service.SysRolePermissionService;
import tech.xs.sys.service.SysRoleService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Slf4j
@Validated
@RestController
@RequestMapping("/role/permission")
public class SysRolePermissionController {

    @Resource
    private SysRolePermissionService sysRolePermissionService;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private SysPermissionService sysPermissionService;

    @PostMapping("/loadEnableRolePermission")
    public ApiResult<Set<String>> loadRoleAllPermission(@RequestBody Set<String> roles) {
        return ApiResult.success(sysRolePermissionService.loadEnableRolePermission(roles));
    }

    @PostMapping("/saveOrUpdate")
    @AuthApi(permissions = PermissionConstant.ROLE_MGR)
    public ApiResult<Void> manualEdit(@Validated @RequestBody EditRolePermissionBo bo) {
        String roleCode = bo.getRoleCode();
        long existRole = sysRoleService.count(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getCode, roleCode));
        Assert.isTrue(existRole > 0, "角色不存在");
        if (!bo.getPermissionCodes().isEmpty()) {
            long existPermission = sysPermissionService.count(Wrappers.<SysPermission>lambdaQuery()
                    .in(SysPermission::getCode, bo.getPermissionCodes()));
            Assert.isTrue(existPermission > 0, "权限不存在");
        }
        List<SysRolePermission> saveDataList = new ArrayList<>();
        Set<String> permissions = bo.getPermissionCodes();
        if (permissions != null) {
            for (String permission : permissions) {
                SysRolePermission sysRolePermission = new SysRolePermission();
                sysRolePermission.setRoleCode(roleCode);
                sysRolePermission.setPermissionCode(permission);
                saveDataList.add(sysRolePermission);
            }
        }
        List<SysRolePermission> dbDataList = sysRolePermissionService.list(Wrappers.<SysRolePermission>lambdaQuery().eq(SysRolePermission::getRoleCode, roleCode));

        List<SysRolePermission> addList = new ArrayList<>();
        List<SysRolePermission> updateList = new ArrayList<>();
        List<SysRolePermission> deleteList = new ArrayList<>();
        SyncUtil.contrast(saveDataList, dbDataList, addList, updateList, deleteList, new SyncUtil.Compare<SysRolePermission>() {
            @Override
            public boolean compare(SysRolePermission o1, SysRolePermission o2) {
                return o1.getRoleCode().equals(o2.getRoleCode()) && o1.getPermissionCode().equals(o2.getPermissionCode());
            }

            @Override
            public SysRolePermission sourceToTarget(SysRolePermission source, SysRolePermission target) {
                source.setId(target.getId());
                return source;
            }
        });
        log.info("修改角色授权: addList:" + addList + " updateList:" + updateList + " deleteList:" + deleteList);
        if (!addList.isEmpty()) {
            sysRolePermissionService.saveBatch(addList);
        }
        if (!updateList.isEmpty()) {
            sysRolePermissionService.updateBatchById(updateList);
        }
        if (!deleteList.isEmpty()) {
            sysRolePermissionService.removeBatchByIds(deleteList);
        }
        sysRolePermissionService.deleteEnableRolePermissionCache();
        return ApiResult.success();
    }

    @GetMapping("/list/all")
    @AuthApi(permissions = {PermissionConstant.ROLE_MGR})
    public ApiResult<List<SysRolePermission>> listAll(@ModelAttribute ListAllRolePermissionBo bo) {
        return ApiResult.success(sysRolePermissionService.list(Wrappers.<SysRolePermission>lambdaQuery()
                .eq(StrUtil.isNotBlank(bo.getRoleCode()), SysRolePermission::getRoleCode, bo.getRoleCode())
                .orderByAsc(SysRolePermission::getRoleCode, SysRolePermission::getPermissionCode)));
    }

}
